package com.peaksport.pkms.edge.handler;

import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.core.Response.Status;

import org.apache.servicecomb.core.Handler;
import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.swagger.invocation.AsyncResponse;
import org.apache.servicecomb.swagger.invocation.exception.InvocationException;

import com.ibm.icu.math.BigDecimal;
import com.peaksport.framework.exception.PKDevException;
import com.peaksport.framework.util.PKJSONUtils;
import com.peaksport.framework.vo.JSONResultSet;

/**
 * 通过edge访问的服务统一数据格式返回
 * 
 * JSON格式:
 * 	jsonResultSet: {
 * 		resultCode: Code
 * 		resultMsg: 错误/异常消息
 * 		detailExpMsg: 异常堆栈信息
 * 		resultData:[data]: 接口返回实际数据
 * 	} 
 *
 * @author jinbin_guo
 *
 */
public class PKEdgeDataTransferHandler implements Handler {

	@Override
	public void handle(Invocation invocation, AsyncResponse asyncResp) throws Exception {
		if (!needDataTransfer(invocation)) {
			invocation.next(asyncResp);
		} else {
			invocation.next(response -> { 
				Object result = response.getResult();
				if (result instanceof InvocationException) {
					//异常类数据直接返回,在普通微服务上所有的异常都会自动重新封装成InvocationException
					//代码详见com.peaksport.framework.extend.swagger
				} else if (isBasicType(result)) { //基本类型封装成map
					JSONResultSet rs = JSONResultSet.create();
					Map<String, Object> map = new HashMap<>();
					map.put("value", result);
					rs.addResultData(map);
					response.setResult(rs);
				} else {
					JSONResultSet rs = JSONResultSet.create();
					rs.addResultData(result);
					response.setResult(rs);
				}
				asyncResp.handle(response);
			});
		}
	}
	
	/**
	 * 是否数据返回的"基本类型"
	 * @param value
	 * @return
	 */
	private boolean isBasicType(Object value) {
		return value instanceof String ||
				value instanceof Integer ||
				value instanceof Double ||
				value instanceof Boolean ||
				value instanceof BigDecimal ||
				value instanceof Float;
	}
	



	/**
	 * 是否需要进行数据转换
	 * 对oauth不进行数据转换,方便在PKOAuthHandler远程调用是获取到与服务一致的数据返回类型,代码的可读性更高一点
	 * @param invocation
	 * @return
	 */
	private boolean needDataTransfer(Invocation invocation) {
		String serviceName = invocation.getMicroserviceName();
		String schemaId = invocation.getSchemaId();
		boolean b = "pkms-permit".equals(serviceName) && "pkms-permit-pkOAuth".equals(schemaId);
		return !b;
	}
}
